{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Keras example with differential evolution and h5py model saving\n",
    "---\n",
    "\n",
    "<font color='red'> <h3>Tested with TensorFlow 1.10</h3></font>\n",
    "<font color='red'> <h3>This notebook requires h5py pip library, please install it in Hopsworks.</h3></font>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def keras(kernel, pool, dropout):\n",
    "    from tensorflow.python import keras\n",
    "    import tensorflow as tf\n",
    "    from tensorflow.python.keras.datasets import mnist\n",
    "    from tensorflow.python.keras.models import Sequential\n",
    "    from tensorflow.python.keras.layers import Dense, Dropout, Flatten\n",
    "    from tensorflow.python.keras.layers import Conv2D, MaxPooling2D\n",
    "    from tensorflow.python.keras.callbacks import TensorBoard\n",
    "\n",
    "    from tensorflow.python.keras import backend as K\n",
    "    import math\n",
    "    from hops import tensorboard\n",
    "\n",
    "    batch_size = 128\n",
    "    num_classes = 10\n",
    "    epochs = 1\n",
    "\n",
    "    # Input image dimensions\n",
    "    img_rows, img_cols = 28, 28\n",
    "\n",
    "    # The data, shuffled and split between train and test sets\n",
    "    (x_train, y_train), (x_test, y_test) = mnist.load_data()\n",
    "\n",
    "    if K.image_data_format() == 'channels_first':\n",
    "        x_train = x_train.reshape(x_train.shape[0], 1, img_rows, img_cols)\n",
    "        x_test = x_test.reshape(x_test.shape[0], 1, img_rows, img_cols)\n",
    "        input_shape = (1, img_rows, img_cols)\n",
    "    else:\n",
    "        x_train = x_train.reshape(x_train.shape[0], img_rows, img_cols, 1)\n",
    "        x_test = x_test.reshape(x_test.shape[0], img_rows, img_cols, 1)\n",
    "        input_shape = (img_rows, img_cols, 1)\n",
    "\n",
    "    x_train = x_train.astype('float32')\n",
    "    x_test = x_test.astype('float32')\n",
    "    x_train /= 255\n",
    "    x_test /= 255\n",
    "    print('x_train shape:', x_train.shape)\n",
    "    print(x_train.shape[0], 'train samples')\n",
    "    print(x_test.shape[0], 'test samples')\n",
    "\n",
    "    # Convert class vectors to binary class matrices\n",
    "    y_train = keras.utils.to_categorical(y_train, num_classes)\n",
    "    y_test = keras.utils.to_categorical(y_test, num_classes)\n",
    "\n",
    "    model = Sequential()\n",
    "    model.add(Conv2D(32, kernel_size=(kernel, kernel),\n",
    "                     activation='relu',\n",
    "                     input_shape=input_shape))\n",
    "    model.add(Conv2D(64, (kernel, kernel), activation='relu'))\n",
    "    model.add(MaxPooling2D(pool_size=(pool, pool)))\n",
    "    model.add(Dropout(dropout))\n",
    "    model.add(Flatten())\n",
    "    model.add(Dense(128, activation='relu'))\n",
    "    model.add(Dropout(dropout))\n",
    "    model.add(Dense(num_classes, activation='softmax'))\n",
    "\n",
    "    opt = keras.optimizers.Adadelta(1.0)\n",
    "\n",
    "    model.compile(loss=keras.losses.categorical_crossentropy,\n",
    "                  optimizer=opt,\n",
    "                  metrics=['accuracy'])\n",
    "\n",
    "    tb_callback = TensorBoard(log_dir=tensorboard.logdir(), histogram_freq=0,\n",
    "                          write_graph=True, write_images=True)\n",
    "    callbacks = [tb_callback]\n",
    "    callbacks.append(keras.callbacks.ModelCheckpoint(tensorboard.logdir() + '/checkpoint-{epoch}.h5'))\n",
    "\n",
    "    model.fit(x_train, y_train,\n",
    "              batch_size=batch_size,\n",
    "              callbacks=callbacks,\n",
    "              epochs=epochs,\n",
    "              verbose=1,\n",
    "              validation_data=(x_test, y_test))\n",
    "    score = model.evaluate(x_test, y_test, verbose=0)\n",
    "    print('Test loss:', score[0])\n",
    "    print('Test accuracy:', score[1])\n",
    "    return score[1]\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from hops import experiment\n",
    "search_dict = {'kernel': [2,8], 'pool': [2,8], 'dropout': [0.01,0.99]}\n",
    "# local_logdir starts the TensorBoard with a logdir on the local filesystem.\n",
    "# when the job is finished the contents of the logdir will be put automatically in your project\n",
    "experiment.differential_evolution(keras, search_dict, name='keras mnist diff evo', local_logdir=True)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "PySpark",
   "language": "",
   "name": "pysparkkernel"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "python",
    "version": 2
   },
   "mimetype": "text/x-python",
   "name": "pyspark",
   "pygments_lexer": "python2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
